import static org.junit.Assert.*;

import java.security.SecureRandom;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class HandTest{
        
        private Deck deck;
        private static SecureRandom Generator;
        private int handsAmount;
        private Hand hands[];
        private static int[][] theSameRanksHands;
        private static int[][] theSameSuitsHands;
        private Deck deckToDiscard;
        private Hand handsToDiscard[];
        
        @BeforeClass
        public static void setUpBeforeClass() throws Exception{
                Generator = new SecureRandom();
                theSameRanksHands = new int[13][4];
                for(int i=0; i<13; i++) {
                        theSameRanksHands[i] = new int[]{i,13+i,26+i,39+i};
                        for (int j=0; j<4; j++)
                                System.out.println(theSameRanksHands[i][j]);
                }
                theSameSuitsHands = new int[4][4];
                for (int i=0; i<4; i++) {
                        theSameSuitsHands[i] = new int[]{i*13,i*13+1,i*13+2,i*13+3};
                        for (int j=0; j<4; j++)
                                System.out.println(theSameSuitsHands[i][j]);
                }
                
        }

        @AfterClass
        public static void tearDownAfterClass() throws Exception{
                Generator = null;
                for(int i=0; i<13; i++)
                        theSameRanksHands[i] = null;
                        
                theSameRanksHands = null;
                for (int i=0; i<4; i++)
                        theSameSuitsHands[i] = null;
                theSameSuitsHands = null;
        }

        @Before
        public void setUp() throws Exception{
                deck = new Deck();
                handsAmount = Generator.nextInt(5)+2;
                hands = new Hand[handsAmount+1];
                for (int i=1; i<=handsAmount; i++) {
                        hands[i]= new Hand(deck, i);
                }
                deckToDiscard = new Deck();
                handsToDiscard = new Hand[10];
                for (int i=1; i<10; i++) {
                        handsToDiscard[i]= new Hand(deckToDiscard, i);
                }
        }

        @After
        public void tearDown() throws Exception{
                for (int i=1; i<=handsAmount; i++) {
                        hands[i]= null;
                }
                hands = null;
                deck = null;
        }

        @Test
        public void testHand(){
                for (int i=1; i<=handsAmount; i++) {
                        assertNotNull(hands[i]);
                }               
        }

        @Test
        public void testGetReducedHand(){
                for(int i=0; i<13; i++)
                        assertTrue(Hand.getReducedHand(theSameRanksHands[i]).length==1);
                for(int i=0; i<4; i++) {
                        assertArrayEquals(new int[]{13*i},Hand.getReducedHand(theSameSuitsHands[i]));
                }
                assertArrayEquals(new int[]{1,15,30},Hand.getReducedHand(new int[]{1,15,28,30}));
                assertArrayEquals(new int[]{5,20},Hand.getReducedHand(new int[]{5,18,20,25}));
                assertArrayEquals(new int[]{29,43,9},Hand.getReducedHand(new int[]{29,30,43,9}));
        }
        @Test
        public void testGiveWorstCard(){
                for (int j=0; j<4; j++)
                        assertEquals(3,Hand.giveWorstCard(theSameSuitsHands[j]));
                assertEquals(4,Hand.giveWorstCard(new int[]{1,15,28,30}));
                assertEquals(12,Hand.giveWorstCard(new int[]{5,18,20,25}));
                assertEquals(9,Hand.giveWorstCard(new int[]{29,30,43,9}));
                
        }

        @Test
        public void testDiscardAllCards(){
                for (int i=1; i<10; i++) {
                        handsToDiscard[i].discardAllCards(deckToDiscard);
                        assertArrayEquals(new int[]{-1,-1,-1,-1},handsToDiscard[i].getCards());
                }
        }

        @Test
        public void testDrawAllCards(){
                for (int i=1; i<10; i++) {
                        handsToDiscard[i].discardAllCards(deckToDiscard);
                }
                for (int i=1; i<10; i++) {
                        handsToDiscard[i].drawAllCards(deckToDiscard,i);
                        for (int j=0; j<4; j++) {
                                assertFalse("0-1"==handsToDiscard[i].getOneCard(j));;
                        }
                }
        }
        @Test
        public void testChangeCards(){
                String[] oldCards = new String[10];
                for(int i=1; i<10; i++) {
                        oldCards[i] = handsToDiscard[i].getString();
                        handsToDiscard[i].changeCards(deckToDiscard, i, 13);
                        assertFalse(oldCards[i].equals(handsToDiscard[i].getString()));
                }
        }
        

}
